<template>
  <div class="contract-list common-list-container__v2">
    
    <div ref="tableHeaderContainer" class="contract-list-search">
      <div class="contract-list-search-form input-with-append-search">
        <el-input
          v-model.trim="listQueryPage.likeSearch"
          :placeholder="$t('contract.list.searchTip')"
          class="search-input"
          @keyup.enter.native="handleSearch"
        >
          <i slot="prefix" class="el-input__icon el-icon-search"></i>
          <el-button type="primary" slot="append" @click="handleSearch" v-track="Track.formatParams('KEYWORD_SEARCH')">
            {{$t('common.base.search')}}
          </el-button>
        </el-input>

        <el-button class="ml_12" type="plain-third" @click="handleReset" v-track="Track.formatParams('RESET_SEARCH')">
          {{$t('common.base.reset')}}
        </el-button>

        <AdvancedSearch
          ref="popperAdvancedSearchDom"
          class="ml_12"
          :fields="searchFieldInfo"
          :search-model="viewportSearchModel"
          :has-save="false"
          :has-create="false"
          :in-common-use="inCommonUse"
          @changeCommonUse="changeCommonUse"
          @search="handleAdvancedSearch"
        />
      </div>

      <!-- 快捷搜索 S -->
      <div class="mt_12" v-show="packUp">       
        <BaseFilterTagList :label="$t('contract.list.contractStatus')+':'" :active="listQueryPage.contractStatus" :list="dataStatusTabList" :props="{label: 'name', value: 'enName'}" @choose="handleClickQuickSearch($event, 'CONTRACT_STATUS')">
          <template v-slot="{name, type}">
            {{name}}({{ statisticalCount[type] || 0 }})
          </template>
        </BaseFilterTagList>
        <BaseFilterTagList :label="$t('contract.list.createAngle')+':'" :active="listQueryPage.searchType" :list="createViewTabList" :props="{label: 'name', value: 'enName'}" @choose="handleClickQuickSearch($event, 'CREATE_PERSPECTIVE')"></BaseFilterTagList>
        <BaseFilterTagList :label="$t('contract.setting.contractTemplate.text1')+':'" :active="listQueryPage.templateId" :list="contractTemplateListSearch" :props="{label: 'templateName', value: 'id'}" @choose="handleClickQuickSearch($event, 'CONTRACT_TEMPLATE')"></BaseFilterTagList>
      </div>
      <!-- 快捷搜索 E -->
    </div>
    <!-- 搜索E -->

    <div class="bbx-normal-pack-up">
      <div @click="changePackUp">
        <i :class="['iconfont', packUp ? 'icon-Icon_up' : 'icon-more']"></i>
      </div>
    </div>

    <!-- 表格S -->
    <div class="contract-list-table">
      <div ref="tableDoContainer" class="contract-list-table-toolbar">
        <div>
          <el-dropdown v-if="buttonAuth.insert">
            <el-button type="primary" icon="el-icon-plus">{{$t('common.base.create')}}</el-button>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item
                v-for="(item, index) in contractTemplateList"
                :key="index"
              >
                <div @click="handleAdd(item)">{{ item.templateName }}</div>
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>

          <!-- 智能计划 -->
          <el-button
            type="plain-third"
            class="ml_12"
            @click="handleCommand('smartPlan')"
            v-if="isShowCreateSmartPlan && smartPlanButtonTile"
          >
            {{ $t('smartPlan.title') }}
          </el-button>

          <el-button
            type="plain-third"
            class="ml_12"
            @click="handleDelete"
            v-if="buttonAuth.deleted && deleteButtonTile"
            v-track="Track.formatParams('DELETE')"
          >
            {{$t('common.base.batchDelete')}}
          </el-button>

          <!-- 批量操作（除新建以外的其它按钮） -->
          <el-dropdown
            class="ml_12"
            v-if="isShowBatchOperation"
            :hide-on-click="false"
            trigger="click"
            @command="handleCommand"
          >
            <el-button type="plain-third">{{ $t('part.text40') }}</el-button>
            <el-dropdown-menu class="batch-operation-dropdown-menu" slot="dropdown">
              <!-- 新建智能计划 -->
              <el-dropdown-item v-if="isShowCreateSmartPlan" command="smartPlan">
                <div class="dropdown-name">{{ $t('smartPlan.title') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'smartPlan', {tile: smartPlanButtonTile})"
                >
                  <i class="iconfont" :class="[smartPlanButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
              <!-- 删除 -->
              <el-dropdown-item v-if="buttonAuth.deleted" command="delete">
                <div class="dropdown-name">{{ $t('common.base.batchDelete') }}</div>
                <div
                  class="dropdown-iconfont flex-x"
                  @click.stop="tileButton(buttonStorageModule, buttonStorageKey, 'delete', {tile: deleteButtonTile})"
                >
                  <i class="iconfont" :class="[deleteButtonTile ? 'icon-pushpin-fill' : 'icon-pushpin']"></i>
                </div>
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
        </div>
        <div>
          <el-dropdown trigger="click">
            <span class="el-dropdown-link cur-point">
              {{$t('common.base.moreOperator')}}
              <i class="iconfont icon-fdn-select"></i>
            </span>
            <el-dropdown-menu slot="dropdown">
              <el-dropdown-item>
                <div @click="handleExport(false)" v-track="Track.formatParams('EXPORT', null, 'MORE_ACTIONS')">{{$t('common.base.export')}}</div>
              </el-dropdown-item>

              <el-dropdown-item>
                <div @click="handleExport(true)" v-track="Track.formatParams('EXPORT_ALL', null, 'MORE_ACTIONS')">{{$t('common.base.exportAll')}}</div>
              </el-dropdown-item>
            </el-dropdown-menu>
          </el-dropdown>
          <span class="cur-point mar-l-24 more-list" @click="handleSelectColumn" v-track="Track.formatParams('SELECT_COLUMN')">
            {{$t('common.base.choiceCol')}}
            <i class="iconfont icon-fdn-select"></i>
          </span>
        </div>
      </div>

      <el-table
        v-table-style
        ref="tableRef"
        v-loading="listLoading"
        header-row-class-name="common-list-table-header__v2"
        :data="tableData"
        stripe
        border
        @select="handleSelection"
        @select-all="handleSelection"
        @sort-change="sortChangeHandler"
        @header-dragend="headerDragend"
        :class="['bbx-normal-list-box']"
        :height="tableContainerHeight"
      >
        <template slot="empty">
          <BaseListForNoData
            v-show="!listLoading"
            :notice-msg="$t('common.base.tip.noData')"
          ></BaseListForNoData>
        </template>
        <el-table-column
          type="selection"
          width="48"
          align="center"
          fixed="left"
        ></el-table-column>
        <template v-for="column in columns">
          <el-table-column
            v-if="column && column.show"
            show-overflow-tooltip
            :align="column.align"
            :key="column.field"
            :label="column.displayName"
            :min-width="column.minWidth"
            :prop="column.field"
            :sortable="column.sortable"
            :width="column.width"
            :fixed="column.fixLeft || false"
          >
            <template slot-scope="scope">
              <template v-if="column.fieldName === 'contractNo'">
                <div class="link" @click="JumpContractDetail(scope.row)">
                  {{ scope.row.contractNo || '' }}
                </div>
              </template>
              <template v-else-if="column.fieldName === 'customer'">
                {{ (scope.row.customerVO && scope.row.customerVO.name) || '' }}
              </template>
              <template v-else-if="column.fieldName === 'linkman'">
                {{ (scope.row.linkManVO && scope.row.linkManVO.name) || '' }}
              </template>
              <!-- 服务部门 -->
              <template v-else-if="column.fieldName === 'tags'">
                {{ scope.row.tagList | tagName }}
              </template>
              <!-- 负责人 -->
              <template v-else-if="column.fieldName === 'managerPerson'">
                {{ scope.row.manager | tagName }}
              </template>
              <!-- 数据状态 -->
              <template v-else-if="column.fieldName === 'contractStatus'">
                <span
                  class="status-tab"
                  :style="{
                    background: contractStatusBgc[scope.row.contractStatus],
                  }"
                  >{{ getStatusValue[scope.row.contractStatus] }}</span
                >
              </template>
              <!-- 创建人 -->
              <template v-else-if="column.fieldName === 'creater'">
                {{ scope.row.createUser.displayName || '' }}
              </template>
              <template v-else-if="column.formType === 'product'">
                {{ scope.row.productVO | tagName }}
              </template>
              <template v-else-if="column.fieldName === 'otherAmount'">
                {{ getCurrencyAmountView(column, scope.row) }}
              </template>
              <template v-else-if="column.fieldName === 'discountAmount'">
                {{ getCurrencyAmountView(column, scope.row) }}
              </template>
              <template v-else-if="column.fieldName === 'contractAmount'">
                {{ getCurrencyAmountView(column, scope.row) }}
              </template>
              <template v-else-if="column.fieldName === 'quotationAmount'">
                {{ getCurrencyAmountView(column, scope.row) }}
              </template>
              <template v-else-if="column.fieldName === 'procureAmount'">
                {{ getCurrencyAmountView(column, scope.row) }}
              </template>
              <!-- 国际货币 -->
              <template v-else-if="column.formType === 'currency' && scope.row.attributeMap">
                {{ $formatFormField(column, scope.row, 'attributeMap') }}
              </template>
              <!-- 富文本 -->
              <template v-else-if="column.formType === 'richtext'">
                <div class='view-detail-btn' @click.stop="openRichtextVisible(scope.row, column)">
                  <span v-if="scope.row.attributeMap && scope.row.attributeMap[column.fieldName]">{{$t('common.base.view')}}</span>
                </div>
              </template>
              <template v-else>
                {{
                  $formatFormField(column, scope.row, 'attributeMap')
                }}
              </template>
            </template>
          </el-table-column>
        </template>
        <el-table-column fixed="right" :label="$t('common.fields.action.displayName')" width="100">
          <template slot-scope="scope">
            <div class="link" @click="JumpContractDetail(scope.row)">{{$t('common.base.detail')}}</div>
          </template>
        </el-table-column>
      </el-table>
      <!-- 表格E -->

      <!-- 分页 S -->
      <div
        ref="tableFooterContainer"
        class="table-footer bbx-normal-table-footer-10"
      >
        <div class="list-info">
          <i18n path="common.base.table.totalCount">
            <span place="count" class="level-padding">{{ page.total }}</span>
          </i18n>
          <template v-if="multipleSelection&&multipleSelection.length>0">
            <i18n path="common.base.table.selectedNth">
              <span
                place="count"
                class="contract-selected-count"
                @click="multipleSelectionPanelShow = true"
              >{{ multipleSelection.length }}</span>
            </i18n>
            <span class="contract-selected-count" @click="toggleClearSelection()">{{$t('common.base.clear')}}</span>
          </template>
        </div>
        <el-pagination
          background
          @current-change="handlePageJump"
          @size-change="handleSizeChange"
          :page-sizes="defaultTableData.defaultPageSizes"
          :page-size="page.pageSize"
          :current-page="page.pageNum"
          layout="prev, pager, next, sizes, jumper"
          :total="page.total"
        >
        </el-pagination>
      </div>
      <!-- 分页 E -->
    </div>

    <!-- 高级搜索框 -->
    <!-- <base-search-drawer
      :show.sync="visible"
      :storage-key="advancedColumnNumStorageKey"
      @reset="handleReset"
      @search="handleSearch"
      @changeWidth="setAdvanceSearchColumn"
      @getColumnNum="setAdvanceSearchColumn"
    >
      <base-search-panel
        ref="searchPanel"
        :customer-obj="customerObj"
        :product-obj="productObj"
        :column-num="columnNum"
        :fields="advanceSearchColumn"
        timeValueType="number"
      ></base-search-panel>
    </base-search-drawer> -->

    <!-- 选择列 -->
    <biz-select-column
      ref="advanced"
      @save="saveColumnStatus"
      mode="contract"
    />

    <!-- 导出 -->
    <base-export-group
      ref="exportRef"
      :alert="exportAlert"
      :columns="exportColumnList"
      :build-params="exportParamsBuild"
      :group="true"
      :validate="exportCountCheck"
      method="post"
      action="/excels/contract/export"
    />

    <!-- start 已选择列表 -->
    <base-panel
      class="base-panel contract-panel"
      :show.sync="multipleSelectionPanelShow"
      width="420px"
    >
      <h3 slot="title">
        <span>{{$t('contract.list.exportPanel.title')}}({{ multipleSelection.length }})</span>
        <i
          v-if="multipleSelection.length"
          class="iconfont icon-qingkongshanchu contract-template-panel-btn"
          @click="toggleClearSelection()"
          :title="$t('contract.list.exportPanel.clearIconTip')"
          data-placement="right"
          v-tooltip
        ></i>
      </h3>

      <!-- 选中数据的弹框 -->
      <div class="contract-panel-selected">
        <div
          class="contract-panel-selected-tip"
          v-if="!multipleSelection.length"
        >
          <img :src="noDataImage" />
          <p>{{$t('contract.list.exportPanel.noData')}}</p>
        </div>
        <template v-else>
          <div class="contract-panel-list">
            <div class="contract-selected-row contract-panel-list-head">
              <span class="contract-panel-list-head-name">{{$t('contract.contract')}}</span>
            </div>
            <div
              class="contract-selected-row"
              v-for="c in multipleSelection"
              :key="c.id"
            >
              <span class="contract-selected-sn">{{ c.contractName }}</span>
              <button
                type="button"
                class="contract-selected-delete"
                @click="removeFromSelection(c)"
              >
                <i class="iconfont icon-fe-close"></i>
              </button>
            </div>
          </div>
        </template>
      </div>
    </base-panel>
    <!-- 新建智能计划弹窗 -->
    <createSmartPlanDialog :customers="multipleSelectionCustomers" ref="createSmartPlanDialog" />
    <base-view-rich-text ref="baseViewRichTextRef"></base-view-rich-text>
  </div>
</template>
<script>
import Vue, {
  ref,
  onMounted,
  reactive,
  toRefs,
  computed,
  nextTick,
  set,
} from 'vue';

import { storageGet, storageSet } from '@src/util/storage';
import { parse } from '@src/util/querystring';
/* enum */
import StorageKeyEnum from '@model/enum/StorageKeyEnum.ts';
import Page from '@model/Page';
import _ from 'lodash';
import i18n, { t } from '@src/locales';

import { MessageBox, Message } from 'element-ui';
import { toast } from '@src/util/platform'
/* mixin */
import ManualTriggerMixin from '@src/mixins/manualTriggerMixin'

// api
import {
  contractFieldList,
  getStatusCount,
  getContractField,
  deleteContract,
  checkAuth,
  getContractTemplateList
} from '@src/api/ContractApi';

import BaseSearchDrawer from 'packages/BaseSearchDrawer';
import BaseSearchPanel from 'packages/BaseSearchPanel';

import {
  getColumnFields,
  getAdvancedFields,
  dataStatusTabList,
  createViewTabList,
  getStatusValue,
  contractStatusBgc,
} from './fields';
import { defaultTableData } from '@src/util/table'

import { serviceTimeFields } from '@src/modules/productV2/productWarrantyServiceItem/productWarrantyItemListPage/fields.js';

const CONTRACT_LIST_KEY = 'contract_list';
import { jumpContractAdd, jumpContractEdit, jumpContractDetail } from '@src/modules/contract/util/JumpContractUtil.js';
import { CURRENCY_SUFFIX } from '@src/util/currency';
// 国际化灰度
import useFormMultiLanguage from '@hooks/useFormMultiLanguage'
const { internationalGray } = useFormMultiLanguage();

import { formatDate, useFormTimezone } from 'pub-bbx-utils'
const { disposeFormListViewTime } = useFormTimezone()
import { getOssUrl } from '@src/util/assets'
const noDataImage = getOssUrl('/no_data.png')
import AdvancedSearch from '@src/component/AdvancedSearch/index.vue';

import { useAdvancedSearchState } from '@src/common/advancedSearch.ts'
export default {
  name: 'contract-list',
  mixins: [ManualTriggerMixin],
  components: {
    BaseSearchDrawer,
    BaseSearchPanel,
    AdvancedSearch,
  },
  filters: {
    tagName(value) {
      if (!value || !Array.isArray(value) || !value.length) return '';

      return value
        .filter(
          item =>
            (item && item.tagName) ||
            (item && item.displayName) ||
            (item && item.name)
        )
        .map(item => item.tagName || item.displayName || item.name)
        .join('，');
    },
  },
  setup(props, {}) {
    const advanced = ref(null);
    const tableRef = ref(null);
    const exportRef = ref(null);
    const searchPanel = ref(null);

    const tableHeaderContainer = ref(null);
    const tableDoContainer = ref(null);
    const tableFooterContainer = ref(null);
    const baseViewRichTextRef = ref(null);

    const Track = Vue.prototype.$track;

    const data = reactive({
      dataStatusTabList: dataStatusTabList(),
      createViewTabList: createViewTabList(),
      packUp: true,
      listLoading: true,
      columns: [], // 表头
      dataList: [], // 列表数据
      page: new Page(), // page 对象
      listQueryPage: {},
      visible: false,
      isFirstOpenAdvancedSearch: true, // 是否是第一次打开高级搜索
      columnNum: 1,
      advancedColumnNumStorageKey: StorageKeyEnum.ContractListAdvancedColumnNum,
      multipleSelectionPanelShow: false,
      multipleSelection: [],
      statisticalCount: {},
      tableContainerHeight: '440px',
      buttonAuth: {},
      productSubForm: [], // 导出列产品子表单数据
      productWarrantyServiceSubForm: [], // 导出列产品质保服务子表单数据
      systemForm: [], // 导出系统字段
      advanceSearchColumn: [],
      selectedLimit: 500,
      contractTemplateList: [], // 合同模板列表
      contractTemplateListSearch: [], // 合同模板列表
      customerObj: {},
      productObj: {},
      buttonStorageModule: 'contractList',
      buttonStorageKey: 'contractListButtonData',
      noDataImage
    });

    const realSearchFields = computed(()=>{
      return data.advanceSearchColumn.filter(i=>i.fieldName !== 'templateName' && i.fieldName !== 'contractStatus' && i.fieldName !== 'address');
    })

    

    // 页面参数
    let query = parse(window.location.search) || {};

    const selectedIds = computed(() => {
      return data.multipleSelection.map(item => item.id);
    });
    /** 打开富文本弹窗 */
    const openRichtextVisible = (row, column)=> {
     const richtextId = row?.attributeMap?.[column.fieldName] || ''
      baseViewRichTextRef.value.openDialog(richtextId)
    }

    // 计算已选择
    const selectionCompute = selection => {
      let tv = [];
      tv = data.multipleSelection.filter(ms =>
        data.dataList.every(c => c.id !== ms.id)
      );
      tv = _.uniqWith([...tv, ...selection], _.isEqual);

      return tv;
    };

    // 勾选checkbox
    const handleSelection = selection => {
      let tv = selectionCompute(selection);

      let original = data.multipleSelection.filter(ms =>
        data.dataList.some(cs => cs.id === ms.id)
      );

      let unSelected = data.dataList.filter(c =>
        original.every(oc => oc.id !== c.id)
      );

      if (tv.length > data.selectedLimit) {
        nextTick(() => {
          original.length > 0
            ? unSelected.forEach(row => {
                tableRef.value.toggleRowSelection(row, false);
              })
            : tableRef.value.clearSelection();
        });
        return toast(
          i18n.t('common.base.tip.choiceLimit', {limit: this.selectedLimit}),
          'error'
        );
      }

      data.multipleSelection = tv;
      nextTick(() => {
        knowTableContainerHeight();
      });
    };

    // 清空选择项
    const toggleClearSelection = rows => {
      let isNotOnCurrentPage = false;
      let row = undefined;

      if (rows) {
        for (let i = 0; i < rows.length; i++) {
          row = rows[i];
          isNotOnCurrentPage = data.dataList.every(item => {
            return item.id !== row.id;
          });
          if (isNotOnCurrentPage) return;
        }
        rows.forEach(row => {
          tableRef.value.toggleRowSelection(row);
        });
      } else {
        data.multipleSelection = [];
        tableRef.value.clearSelection();
      }
    };

    // 删除选中的合同
    const removeFromSelection = c => {
      if (!c || !c.id) return;

      data.multipleSelection = data.multipleSelection.filter(
        ms => ms.id !== c.id
      );
      data.multipleSelection.length < 1
        ? toggleClearSelection()
        : toggleClearSelection([c]);
    };

    // 选择列排序
    const buildSortFields = (originFields = [], fieldsMap = {}) => {
      let fields = [];
      let unsortedFields = [];

      originFields.forEach(originField => {
        let { fieldName } = originField;
        let field = fieldsMap[fieldName];

        if (field) {
          let { index } = field;
          fields[index] = originField;
        } else {
          unsortedFields.push(originField);
        }
      });

      return fields.concat(unsortedFields);
    };

    // 构建表格选择列字段
    const buildColumns = async () => {
      // 获取缓存在本地的选择列配置
      const localStorageData = await getLocalStorageData();
      const columnStatus = localStorageData.columnStatus || [];

      const localColumns = columnStatus
        .map(i => (typeof i == 'string' ? { field: i, show: true } : i))
        .reduce((acc, col, currentIndex) => {
          acc[col.field] = {
            field: col,
            index: currentIndex,
          };
          return acc;
        }, {});

      let customFields = [...data.columns];
      if (Array.isArray(columnStatus) && columnStatus.length > 0) {
        // 有本地缓存--列表排序
        customFields = buildSortFields(customFields, localColumns);
      }

      const columns = customFields.map(col => {
        // 选择列配置 是否勾选（显示）&宽度
        let show = col.show === true;
        let width = col.width;
        let localField = localColumns[col.field]?.field || null;
        let fixLeft = localField?.fixLeft || null;

        if (null != localField) {
          if (localField.width) {
            width =
              typeof localField.width == 'number'
                ? `${localField.width}px`
                : localField.width;
          }
          show = localField.show !== false;
        }

        col.show = show;
        col.width = width;
        col.minWidth = col.width || 150;
        col.type = 'column';
        col['fixLeft'] = fixLeft && 'left'
        return col;
      });

      data.columns = [];
      nextTick(() => {
        data.columns = columns;
      });
    };

    // ======================= 选择列start
    // 获取本地localstorage
    const getLocalStorageData = () => {
      const dataStr = storageGet(CONTRACT_LIST_KEY, '{}');
      return JSON.parse(dataStr);
    };

    // 保存数据到本地localstorage
    const saveDataToStorage = (key, value) => {
      const data = getLocalStorageData();
      data[key] = value;
      storageSet(CONTRACT_LIST_KEY, JSON.stringify(data));
    };

    const popperAdvancedSearchDom = ref(null)

    

    // 点击选择列
    const handleSelectColumn = () => {
      // 先把模板id去掉，不传到选择列组件里面，选择列组件对模板id做了处理
      let arr = data.columns.map(item => {
        const { templateId, ...other } = item;
        return {
          ...other
        }
      })
      advanced.value.open(arr);
    };

    // 保存选择列
    const saveColumnStatus = event => {
      let columns = event.data || [];

      data.columns = [];
      nextTick(() => {
        data.columns = columns.slice();
        saveColumnStatusToStorage();
      });
      Message.success(t('common.base.saveSuccess'))
    };

    // 保存选择列配置到本地
    const saveColumnStatusToStorage = () => {
      const localStorageData = getLocalStorageData();
      let columnsStatus = null;

      // 判断是否存储选择列
      const columnsList = data.columns.map(c => ({
        field: c.fieldName,
        show: c.show,
        width: c.width,
        fixLeft: c.fixLeft
      }));

      if (localStorageData.columnStatus) {
        localStorageData.columnStatus = columnsList;
        columnsStatus = localStorageData.columnStatus;
      } else {
        columnsStatus = columnsList;
      }

      saveDataToStorage('columnStatus', columnsStatus);
    };
    // ======================= 选择列end

    // 表头改变
    const headerDragend = (newWidth, oldWidth, column, event) => {
      let ret = data.columns
        .map(item => {
          if (item.fieldName === column.property) {
            item.width = column.width;
          }
          return item;
        })
        .map(item => {
          return {
            field: item.field,
            show: item.show,
            width: item.width,
          };
        });
      modifyColumnStatus({ type: 'column', ret });
    };

    // 修改选择列设置
    const modifyColumnStatus = event => {
      let columns = event.data || [],
        colMap = columns.reduce(
          (acc, col) => (acc[col.field] = col) && acc,
          {}
        );
      data.columns.forEach(col => {
        let newCol = colMap[col.field];
        if (null != newCol) {
          set(col, 'show', newCol.show);
          set(col, 'width', newCol.width);
        }
      });

      saveColumnStatusToStorage();
    };

    // 高级搜索字段
    // const advanceSearchColumn = computed(() => {
    //   return [...data.columns].filter(
    //     item => item?.isSearch && item?.isSearch == 1
    //   );
    // });

    // 获取数据状态的总数
    const getCount = () => {
      getStatusCount()
        .then(res => {
          if (!res.success) return toast(res.message, 'error');
          data.statisticalCount = res.result;
        })
        .finally(() => {});
    };

    // 获取表头
    const getTableHeader = async () => {
      data.listLoading = true;
      let fields = [];
      try {
        let ret = await contractFieldList({
          templateId: data.listQueryPage.templateId
        });

        let { result: list } = ret;

        if (ret.success) {
          // 过滤掉重复字段,系统字段，不需要显示的自定义字段
          fields = list
            .filter(
              item =>
                item.formType != 'attachment' &&
                item.formType != 'autograph' &&
                item.formType != 'info' &&
                item.formType != 'separator' &&
                item.formType != 'subSparePart' &&
                item.formType != 'subForm' && 
                item.isHidden !== 1
            )
            .map(field => {
              let sortable = false;
              if (
                ['effectiveTime', 'invalidTime', 'contractNo'].includes(field.fieldName) ||
                ['date', 'datetime'].includes(field.formType)
              ) {
                sortable = 'custom';
              }

              return {
                ...field,
                tableName: 'contract',
                field: field.fieldName,
                label: field.displayName,
                formType: field.formType,
                minWidth: '150',
                sortable,
                show: !!field.isSystem,
              };
            });
          data.columns = [...fields, ...getColumnFields()];

          // 导出系统字段
          data.systemForm = [...fields, ...getAdvancedFields()];


          // 导出产品子表单的数据
          const productField = list.find(item => item.formType === 'product')
          data.productSubForm = []; // 清空数据
          if(productField !== undefined && productField?.subFormFieldList.length > 0) {
            data.productSubForm = [...(productField?.subFormFieldList || [])].map(p => {
              return {
                ...p,
                tableName: 'contract',
                field: p.fieldName,
                label: p.displayName,
              };
            })
          }
          
          // 导出产品质保服务子表单
          const productWarrantyServiceField = list.find(item => item.formType === 'productWarrantyService')
          data.productWarrantyServiceSubForm = [];
          if (productWarrantyServiceField !== undefined && productWarrantyServiceField?.subFormFieldList.length > 0) {
            data.productWarrantyServiceSubForm = [...(productWarrantyServiceField?.subFormFieldList || []), ...(serviceTimeFields || [])].map(p => {
              return {
                ...p,
                tableName: 'contract',
                field: p.fieldName,
                label: p.displayName,
              };
            })
          }

          buildColumns();

          const columns = _.cloneDeep(data.columns)
          data.advanceSearchColumn = [...columns].map(item => {
            // 产品支持高级搜索，单选，字段数据处理
            if (item.formType === 'product') {
              item.field = 'product'
              item.fieldName = 'product'
              item.isSearch = 1
              item.isSystem = 1
              item.setting = {}
              item.subFormFieldList = []
            }
            return item
          }).filter(
            item => item.isSystem || (item?.isSearch && item?.isSearch == 1)
          );
        }
      } catch (err) {
        console.log('error => fetchFields', err);
      } finally {
        data.listLoading = false;
      }
    };

    /* 显示高级搜索 */ 
    const showAdvancedSearch = () => {
      if (data.isFirstOpenAdvancedSearch) {
        // 高级搜索数据处理
        if (query.customerId) {
          data.customerObj = {
            id: query.customerId,
            name: query.customerName
          }
        }
        if (query.productId) {
          data.productObj = {
            id: query.productId,
            name: query.productName
          }
        }
      }
      data.isFirstOpenAdvancedSearch = false
      data.visible = true
    }

    /**  构建搜索参数 */
    const buildSearchParams = (isFirst) => {
      let advancedSearchParams = searchPanel.value
        ? searchPanel.value.buildParams()
        : {};

      let {
        conditions = [],
        creater: createUid,
        linkman: linkmanId,
        managerPerson: manager,
        tags = [],
      } = advancedSearchParams || {};

      const searchListFormList = conditions.map(item => {
        let {
          property: fieldName,
          value: valueList,
          operator,
          inValue,
        } = item || {};
        let dateObj = {};
        let otherObj = {};
        let cascaderObj = {};
        if (operator === 'between') {
          dateObj = {
            fieldName,
            endValue: item.betweenValue2,
            startValue: item.betweenValue1,
          };
          if(item?.inValue?.length) dateObj.valueList = item.inValue;
        } else if (operator == 'cascader') {
          cascaderObj = {
            fieldName,
            valueList: inValue,
          };
        } else {
          otherObj = {
            fieldName,
            valueList: [valueList],
          };
        }
        return {
          ...dateObj,
          ...cascaderObj,
          ...otherObj,
        };
      });

      delete advancedSearchParams.conditions;
      delete advancedSearchParams.creater;
      delete advancedSearchParams.linkman;
      delete advancedSearchParams.managerPerson;
      delete advancedSearchParams.tags;

      if (advancedSearchParams.productId) {
        advancedSearchParams.product = [advancedSearchParams.productId]
        delete advancedSearchParams.productId
      }

      // 第一次进入页面时赋值传参
      if ((isFirst || !data.visible) && query.customerId) {
        advancedSearchParams.customerId = query.customerId
      }
      if ((isFirst || !data.visible) && query.productId) {
        advancedSearchParams.product = [query.productId]
      }

      return {
        ...data.listQueryPage,
        createUid,
        linkmanId,
        manager,
        tags: tags[0]?.id ? [tags[0]?.id] : [],
        ...advancedSearchParams,
        ...conditionParams.value,
        searchListFormList: [...searchListFormList],
      };
    };

    /* 重置搜索参数 */
    const resetParams = () => { 
      if (searchPanel.value) {
        searchPanel.value.form = {}
        searchPanel.value.initFormVal()
      }
      // 重置其它页面传过来的参数
      query = {}
      data.visible = false
      data.listQueryPage = initListQueryPage()
      resetAdvancedConditions()
      return data.listQueryPage
    } 

    /* 初始化搜索参数 */ 
    const initListQueryPage = () => {
      return {
        likeSearch: '', // 关键字
        pageSize: 10, // 每页显示条目
        pageNum: 1, // 当前页数
        column: '', // 排序列
        asc: true, // 升序降序
        contractStatus: 'EFFECTIVE', // 默认已生效
        searchType: '',
        total: 0,
        templateId: "",
        tasg: [],
        searchListFormList: [],
      }
    }

    /* 把选中的匹配出来 */
    const matchSelected = () => {
      if (!data.multipleSelection.length) return;

      // 计算当前页已选择的数据
      const selected =
        data.dataList.filter(ms =>
          data.multipleSelection.some(cs => cs.id === ms.id)
        ) || [];

      nextTick(() => {
        selected.forEach(row => {
          tableRef.value.toggleRowSelection(row, true);
        });
      });
    };

    // 获取列表数据
    const getTableList = (isFirst, isReset) => {
      const searchParams = isReset ? resetParams() : buildSearchParams(isFirst);

      data.listLoading = true;
      data.dataList = [];
      try {
        getContractField(searchParams).then(res => {
          if (!res.success) return toast(res.message, 'error');

          let { list } = res.result;

          if (!list) data.page = new Page();

          data.page.merge(res.result);

          data.dataList = list;

          data.listLoading = false;

          matchSelected();
        });
      } catch (error) {
        console.log('error=>', error);
      }
    };

    // 搜索 & 回车
    const handleSearch = (isFirst) => {
      getTableList(isFirst);
      data.visible = false;
    };

    // 点击快捷搜索
    const handleClickQuickSearch = ({ enName, id }, type) => {
      Track.clickStat(Track.formatParams('QUICK_SEARCH', type));
      
      if (type === 'CONTRACT_STATUS') {
        data.listQueryPage.contractStatus = enName
        
      } else if (type === 'CREATE_PERSPECTIVE') {
        data.listQueryPage.searchType = enName
      } else if (type === 'CONTRACT_TEMPLATE') {
        data.listQueryPage.templateId = id;
        getTableHeader()
        resetAdvancedConditions()
      }

      toggleClearSelection();

      // 重置高级搜索的值
      if (searchPanel.value) {
        searchPanel.value.form = {}
        searchPanel.value.initFormVal()
      }
      // 重置其它页面传过来的参数
      query = {}

      data.listQueryPage.pageNum = 1;
      getTableList();
    };

    // 重置
    const handleReset = () => {
      getTableList(false, true)
    };

    // pageSize 改变时触发
    const handleSizeChange = pageSize => {
      data.listQueryPage.pageSize = pageSize;
      data.listQueryPage.pageNum = 1;
      getTableList();
    };

    // 页数改变时触发
    const handlePageJump = pageNum => {
      data.listQueryPage.pageNum = pageNum;
      data.dataList = [];
      getTableList();
    };

    // 排序
    const sortChangeHandler = option => {
      const { column, order, prop } = option;
      if (!order) {
        data.listQueryPage.column = ''
        data.listQueryPage.asc = true
        return getTableList()
      }
      const sortedField =
        data.columns.filter(item => item.fieldName === prop)[0] || {};
      data.listQueryPage.column = sortedField.sortName || sortedField.fieldName;
      data.listQueryPage.asc = order === 'descending' ? false : true;
      getTableList();
    };

    // 新建
    const handleAdd = (item) => {
      Track.clickStat(Track.formatParams('TO_CREATE'));

      jumpContractAdd(item)
    };

    // 跳到合同详情页面
    const JumpContractDetail = (item) => {
      const { id, contractStatus } = item || {};

      if (!id) return;

      // 草稿跳转新建页面
      if (contractStatus == 'DRAFT') {
        jumpContractEdit(item)
      } else {
        jumpContractDetail(item)
      }
    };

    // 删除
    const handleDelete = async () => {
      if (!data.multipleSelection.length) {
        return toast(i18n.t('contract.list.handleDelete.noChoiceTip'), 'warning');
      }

      MessageBox.confirm(
        i18n.t('contract.delContract.confirm.msg'),
        i18n.t('contract.delContract.confirm.title'),
        {
          type: 'warning',
        }
      )
        .then(() => {
          deleteContract(selectedIds.value).then(res => {
            if (!res.success) {
              return toast(res.message, 'error');
            }

            toast(i18n.t('common.base.deleteSuccess'), 'success');

            handleReset();
            toggleClearSelection();
          });
        })
        .catch(() => {
          toggleClearSelection();
        });
    };

    // ================== 导出S
    const exportColumnList = computed(() => {
      const systemInfo = {
        label: i18n.t('contract.setting.contractInformation'),
        value: 'systemChecked',
        columns: [...data.systemForm].map(item => {
          item.export = true;
          item.label = item.displayName;
          item.value = item.fieldName;
          return item;
        }),
      };

      // 产品子表单
      const productInfo = {
        label: i18n.t('contract.list.productInfoLabel'),
        value: 'productSubChecked',
        columns: data.productSubForm.map(item => {
          item.export = true;
          return item;
        }),
      };

      const productWarrantyServiceInfo = {
        label: i18n.t('contract.setting.productQualityAssuranceService'),
        value: 'productWarraySubChecked',
        columns: [...(data.productWarrantyServiceSubForm || [])].map(item => {
          item.export = true;
          return item;
        }),
      }

      let column = [systemInfo, productInfo, productWarrantyServiceInfo].filter(item => {
        return item.columns && item.columns.length > 0;
      });

      return column;
    });

    // 导出提示
    const exportAlert = (result, params = {}) => {
      toast(result.message, result.status === 0 ? 'success' : 'error');
      toggleClearSelection();
    };

    // 导出 & 导出全部
    const handleExport = isExportAll => {
      let ids = [];
      let fileName = `${formatDate(
        new Date(),
        i18n.t('contract.list.handleExport.exportFileName', {date: 'YYYY-MM-DD'})
      )}`;

      if (!isExportAll) {
        if (!data.multipleSelection.length) {
          return toast(i18n.t('common.base.tip.exportNoChoice'), 'warning');
        }
        ids = selectedIds.value;
      }

      exportRef.value.open(ids, fileName, false);
    };

    // 构建导出参数
    const exportParamsBuild = (checkedMap, ids) => {
      let { productSubChecked, systemChecked, productWarraySubChecked } = checkedMap || {};
      let checkArr = [...(productSubChecked || []), ...(systemChecked || []), ...(productWarraySubChecked || [])];
      let exportAll = !ids || ids.length == 0;
      return {
        ...buildSearchParams(),
        id: ids,
        fieldList: checkArr || [],
        totalCount: exportAll ? data.page.total : selectedIds.value.length,
      };
    };

    /**
     * @description 检测导出条数
     * @return {String | null}
     */
    const exportCountCheck = (ids, max) => {
      let exportAll = !ids || ids.length == 0;

      return exportAll && data.page.total > max
        ? i18n.t('common.base.tip.exportLimit', { max })
        : null;
    };
    // ================== 导出E

    // 设置高级搜索展示列数
    const setAdvanceSearchColumn = command => {
      data.columnNum = Number(command);
    };

    /**
     * @des 获取列表当前的可滚动高度
     */
    const knowTableContainerHeight = () => {
      let min = 440;
      try {
        let window_ = window.innerHeight;
        let header = tableHeaderContainer.value?.offsetHeight || 0;
        let do_ = tableDoContainer.value?.offsetHeight || 0;
        let footer = tableFooterContainer.value?.offsetHeight || 0;
        min = window_ - header * 1 - do_ * 1 - footer * 1 - 24 - 16 * 3;
        min = min > 440 ? min : 440;
      } catch (error) {
        console.warn(error, 'error try catch');
      }
      data.tableContainerHeight = `${min}px`;
    };

    const changePackUp = () => {
      data.packUp = !data.packUp;
      nextTick(() => {
        knowTableContainerHeight();
      });
    };

    // 获取按钮权限
    const getBtnAuth = () => {
      checkAuth().then(res => {
        if (!res.success) return toast(res.message, 'error');
        data.buttonAuth = { ...res.result };
      });
    };

    // 获取合同模板
    const fetchContractTemplate = async() => {
      try {
        let ret = await getContractTemplateList();

        const { success, message, result } = ret || {};

        if (!success) return toast(message, 'error');

        data.contractTemplateList = (result || []).filter(item => item.enabled);

        data.contractTemplateListSearch = [ 
          {
            id: "",
            templateName: i18n.t('common.base.all')
          },
          ...data.contractTemplateList
        ]

      } catch (err) {
        console.log('error => fetchContractTemplate', err);
      }
    }

    /* ----------币种相关 start---------- */
    const getCurrencyAmountView = (column, row) => {
      const fieldName = column.fieldName;
      const currency = row[fieldName + CURRENCY_SUFFIX] || 'CNY';

      return internationalGray ? `${row[fieldName]} ${currency}` : row[fieldName];
    }
    /* ----------币种相关 end---------- */

    onMounted(async () => {
      data.listQueryPage = initListQueryPage()
      getBtnAuth();
      await getCount();
      await getTableList(true);
      await getTableHeader();
      fetchContractTemplate()

      nextTick(() => {
        knowTableContainerHeight();
        window.onresize = _.debounce(() => {
          knowTableContainerHeight();
        }, 500);
      });

      // 对外开放刷新方法，用于其他tab刷新本tab数据
      window.__exports__refresh = async () => {
        handleSearch(true)
      };
    });
    
    const tableData = computed(() => {
      let columns = []
      // disposeFormListViewTime方法里面传入的columns把formType为date转为datetime
      // 是因为date经过disposeFormListViewTime转换为年月日，datetime转换后为年月日时分秒
      // 高级搜索需要date类型，所以不能改源数据
      data.columns.map(item => {
        let newItem = { ...item }
        const { formType, fieldName } = item
        // 生效日期和失效日期不更改，其他的更改formType
        if(formType === 'date' && (fieldName !== 'effectiveTime' && fieldName !== 'invalidTime')){
          newItem.formType = 'datetime'
        }
        columns.push(newItem)
      })
      return disposeFormListViewTime(data.dataList, columns)
    })

    function searchModelFilter(model){
      let model_ = _.cloneDeep(model)
      if(model_?.systemConditions?.length){
        model_.systemConditions = model_.systemConditions.map(i=>{
          if(i.property === 'linkman'){
            i.property = 'linkmanId'
            i.value = i.value.id
          }else if(i.property === 'creater'){
            i.property = 'createUid'
          }else if(i.property === 'productId'){
            i.property = 'product'
          }else if(i.property === 'tagIds'){
            i.property = 'tags'
          }
          return i
        })
      }
      return model_
    }

    const { searchFieldInfo, 
      handleAdvancedSearch, 
      viewportSearchModel, 
      inCommonUse, 
      changeCommonUse, 
      resetAdvancedConditions,
      conditionParams,
      recoverCommonUse, 
    } = useAdvancedSearchState(realSearchFields, saveDataToStorage, getLocalStorageData, popperAdvancedSearchDom, handleSearch, searchModelFilter)

    recoverCommonUse()

    return {
      defaultTableData,
      tableData,
      advanced,
      tableRef,
      exportRef,
      searchPanel,
      ...toRefs(data),
      toggleClearSelection,
      headerDragend,
      handleSearch,
      handleReset,
      handleSizeChange,
      handlePageJump,
      handleSelection,
      sortChangeHandler,
      handleClickQuickSearch,
      showAdvancedSearch,
      handleAdd,
      JumpContractDetail,
      handleDelete,
      handleExport,
      exportColumnList,
      handleSelectColumn,
      saveColumnStatus,
      setAdvanceSearchColumn,
      getStatusValue,
      contractStatusBgc,
      changePackUp,
      tableHeaderContainer,
      tableDoContainer,
      tableFooterContainer,
      exportAlert,
      exportParamsBuild,
      exportCountCheck,
      removeFromSelection,
      Track,
      getCurrencyAmountView,
      openRichtextVisible,
      baseViewRichTextRef,
      searchFieldInfo,
      handleAdvancedSearch, 
      viewportSearchModel,
      inCommonUse, 
      changeCommonUse,
      popperAdvancedSearchDom,
      resetAdvancedConditions,
    };
  },
  computed: {
    // 是否显示批量操作
    isShowBatchOperation() {
      return (
        this.isShowCreateSmartPlan || this.buttonAuth.deleted
      )
    },
    // 已选择合同数据的客户数据
    multipleSelectionCustomers() {
      const customerIds = this.multipleSelection.map(item => item.customerVO)
      return [...new Set(customerIds.map(item => item.id))].map(id => {  
        return customerIds.find(item => item.id === id);  
      })
    },
  },
  async mounted() {
    this.buttonStorageData = await this.getButtonLocalStorageData(this.buttonStorageModule, this.buttonStorageKey)
  },
  methods: {
    handleCommand(command) {
      if (command == 'smartPlan') {
        if (!this.multipleSelection.length) {
          return this.$platform.alert(t('common.placeholder.selectSomething', {0: t('common.contract.detail.text')}))
        }
        this.$refs.createSmartPlanDialog.open()
      } else if (command == 'delete') {
        this.$track.clickStat(this.$track.formatParams('DELETE'))
        this.handleDelete()
      }
    }
  },
};
</script>
<style lang="scss" scoped>
.contract-list {
  height: 100%;
  overflow: auto;
  padding: 12px;
  &-search {
    width: 100%;
    padding: 16px;
    background: #fff;
    box-shadow: 0px 0px 0px 0px rgba(0, 0, 0, 0.06);
    border-radius: 4px;
    &-form {
      display: flex;
      align-items: center;
      justify-content: flex-end;
      .search-input {
        width: 400px;
      }
      .advanced-search-btn {
        margin-left: 25px;
        @include fontColor;
      }
    }
  }
  &-table {
    background-color: #fff;
    border-radius: 4px;
    padding: 16px 16px 0;
    margin-top: 4px;
    &-toolbar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 16px;
      .more-list {
        color: #595959;
        &:hover {
          color: $color-primary;
        }
      }
    }
    .status-tab {
      display: inline-block;
      min-width: 52px;
      max-width: 128px;
      height: 22px;
      line-height: 22px;
      padding: 0 8px;
      font-size: 12px;
      border-radius: 11px;
      text-align: center;
      vertical-align: middle;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      color: #fff;
    }
    .link {
      color: $color-primary-light-6 !important;
      cursor: pointer;
      &:hover {
        text-decoration: underline;
      }
    }
  }
  .contract-selected-count {
    @include fontColor();
    padding: 0 3px;
    width: 15px;
    text-align: center;
    cursor: pointer;
    font-size: 13px;
  }

  // 选中数据弹框样式
  .contract-panel {
    .contract-template-panel-btn {
      cursor: pointer;
      float: right;
      font-size: 14px;
      margin-right: 5px;
      &:hover {
        @include fontColor();
      }
    }
    &-selected {
      font-size: 14px;
      height: calc(100% - 51px);
      &-tip {
        padding-top: 80px;

        img {
          display: block;
          width: 240px;
          margin: 0 auto;
        }

        p {
          text-align: center;
          color: #9a9a9a;
          margin: 30px 0 0 0;
          line-height: 20px;
        }
      }
    }
    &-list {
      height: 100%;
      padding: 10px;
      overflow-y: auto;
      &-head {
        background-color: #f0f5f5;
        color: #333;
        font-size: 14px;
        &-name {
          padding-left: 10px;
          flex: 1;
          @include text-ellipsis;
        }
      }
    }
    .contract-selected-row {
      display: flex;
      flex-flow: row nowrap;
      align-items: center;
      border-bottom: 1px solid #ebeef5;
      font-size: 13px;
      &:hover {
        background-color: #f5f7fa;
        .contract-selected-delete {
          visibility: visible;
        }
      }
      .contract-selected-sn {
        padding-left: 10px;
        width: 100%;
        @include text-ellipsis;
      }
      button.contract-selected-delete {
        padding: 0;
        width: 36px;
        height: 36px;
        border: none;
        background-color: transparent;
        outline: none;
        color: #646b78;
        visibility: hidden;

        i {
          font-size: 14px;
        }

        &:hover {
          color: #e84040;
        }
      }
    }
  }
}
.customer-selected-count {
  @include fontColor();
  padding: 0 3px;
  width: 15px;
  text-align: center;
  cursor: pointer;
  font-size: 13px;
}
</style>
<style lang="scss">
@import "@src/assets/scss/common-list.scss";
</style>